//
//  WebVC.swift
//  YueChat
//
//  Created by IMac on 2024/10/10.
//

import UIKit
import WebKit

class WebVC: BaseVC,WKUIDelegate,WKNavigationDelegate, WKScriptMessageHandler{
    
    var urlStr: String?
    var webView = WKWebView()
    var islogin = Bool()
    var appInfo = DMCCDapp()
    var userContentController = WKUserContentController()
    // 初始化时接收闭包
    var dismissCompletion: (() -> Void)?
    
    @IBOutlet weak var itemView: UIView!
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.navigationBar.isHidden = true
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.navigationController?.navigationBar.isHidden = false
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        itemView.layer.cornerRadius = 16
        itemView.layer.borderWidth = 0.5
        itemView.layer.borderColor = UIColor.gray.cgColor
        wkWebSetup()
        
        
    }
    
    init(appInfo:  DMCCDapp,dismissCompletion: (() -> Void)?) {
        super.init(nibName: nil, bundle: nil)
        self.dismissCompletion = dismissCompletion
        self.appInfo = appInfo
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @IBAction func shareClick(_ sender: Any) {
        self.presentVC(VC: ShareVC(type: .dapp, dapp: appInfo))
    }
    @IBAction func closeClick(_ sender: Any) {
        userContentController.removeScriptMessageHandler(forName: "osnsdk")
        userContentController.removeScriptMessageHandler(forName: "logger")
        dismissCompletion!()
        dismiss(animated: true)
    }
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        print(message.name)
        if message.name == "osnsdk" {
            if let args = message.body as? String {
                print("args: \(args)")
                if let json = args.toJson(){
//                    let command = json["command"] as? String ?? "";
                    runCommand(json: json)
                }
            }
        }else if message.name == "logger" {
            print("webview log: \(message.body)")
        }
    }
    func webCallback(callback:String){
        print("webview callback: \(callback)")
        self.webView.evaluateJavaScript(callback)
    }
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//        var data:[String:Any] = [:]
//        data["isBackground"] = "false"
//        let dataStr = "appStatusCallBack("+(data.toString() ?? "")+")"
//        self.webCallback(callback: dataStr)
    }
//    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
//        self.showAlert(message: message, complete: completionHandler)
//    }
//    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
////        let urlStr = navigationAction.request.url!.absoluteString as String
////        print("urlStr:",urlStr)
//        decisionHandler(.allow)
//    }

    
    func runCommand(json: [String : Any]) {
        let command = json["command"] as? String ?? "";
        print("Command:\(command)")
        switch(command){
        case "Login":
            login(jsons: json);
            break;
        case "OpenDapp":
            OpenDapp(json: json);
            break;
        case "GetUserInfo":
            GetUserInfo(json: json);
            break;
        case "AddFriend":
            AddFriend(userId: json["userID"] as! String)
            break;
        case "GroupInfo":
            GroupInfo(groupId: json["osnID"] as! String)
            break;
        case "Share":
            ShareDapp(json: json);
            break;
        case "OpenBrowser":
            OpenBrowser(json: json)
            break
        case "SetNft":
            SetNft(json: json);
            break;
        case "GoBack":
            dismiss(animated: true)
            break;
        default:
            print("unknown command: \(command)")
            break
        }
    }
    
    func ShareDapp (json:[String:Any]) {
        if let info = json["DappInfo"] {
            var dic: [String: Any]?
            
            if let infoString = info as? String {
                dic = OsnUtils.toJson(infoString)
            } else if let infoDict = info as? [String: Any] {
                dic = infoDict
            }
            
            let litapp = gosnDapp.fromJson(dic!)

            self.presentVC(VC: ShareVC(type: .dapp, dapp: litapp))
//            let nav = MHHYNavigationVC.init(rootViewController: vc)
//            nav.modalPresentationStyle = .fullScreen
//            
//            self.present(nav, animated: true, completion: nil)
        }
    }
    
    func OpenDapp (json:[String:Any]) {
        if let info = json["DappInfo"] {
            var dic: [String: Any]?
            if let infoString = info as? String {
                dic = OsnUtils.toJson(infoString)
            } else if let infoDict = info as? [String: Any] {
                dic = infoDict
            }

            let litapp = gosnDapp.fromJson(dic!)//DMCCDapp.init(card: dic as Any)

            self.presentVC(VC: YLNavigationVC(rootViewController: WebVC(appInfo: litapp, dismissCompletion: {
                                            })))
//            let vc = WebVC(appInfo: litapp)
//            let nav = YLNavigationVC.init(rootViewController: vc)
//            presentVC(VC: nav)
//            present(nav, animated: true, completion: nil)
        }
    }
    
    func OpenBrowser (json:[String:Any]) {
        guard let url = (json["url"] as? String),
              let url = URL(string: url) else {
            return
        }
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
    
    func SetNft (json:[String:Any]) {
        
        guard let urls = json["url"] as? String,
              let portrait = json["portrait"] as? String else{
            return
        }
        
        MHAlert.showCustomAlert(KLocalizedString("SettingNFTImg")) { ac in
            if ac.title == KLocalizedString("Sure") {
                Task {
                    let res = await gosnUser.setPortraitWithUrl(portrait)
                    
                    if res {
                        _ = await gosnUser.setNft(urls )
                        GK_main_async_safe {
                            MHAlert.showMessage("设置成功")
                        }
                        Task {
                            await gosnUser.fetchMyInfo()
                        }
                    }
                }
//                DMCCIMService.getInstance().setNFT( (json["portrait"] as! String), link: (json["url"] as! String)) {
////                    DMCCIMService.getInstance().updateUserInfo(fromRemote: gosnUser.myId())
//                    gosnUser.fetchMyInfo()
//                } error: { error in
//                    
//                }
            }
        }

    }
    
    func GetUserInfo (json:[String:Any]) {
        if !islogin {
            var result = [String:String]()
            result["errCode"] = "-1:need login"
            
            let callback = json["callback"] as! String
                
            let tokens = OsnUtils.toString(result)//.dic2Json(result)!
            let formattedCallback = "\(callback)(\(String(describing: tokens)))"
            
            print("callback: \(formattedCallback)")
            
            DispatchQueue.main.async {
                self.webView.evaluateJavaScript(formattedCallback) { _, _ in
                    print("done")
                }
            }
        } else {
            guard let userInfo = gosnUser.getUserInfo(gosnUser.myId()) else {
                  
                return
            }
            
            var result = [String:String]()
            result["userID"] = userInfo.userId
            result["userName"] = userInfo.name
            result["nickName"] = userInfo.getAlias()
            result["portrait"] = userInfo.portrait
            result["extra"] = userInfo.describes

            let callback = json["callback"] as! String
                
            let tokens = OsnUtils.toString(result)!
            let formattedCallback = "\(callback)(\(tokens))"
            
            print("callback: \(formattedCallback)")
            
            DispatchQueue.main.async {
                self.webView.evaluateJavaScript(formattedCallback) { _, _ in
                    print("done")
                }
            }
        }
    }
    
    func login (jsons:[String:Any]) {
        weak var weakSelf = self
        Task {
            await DappSdk.dappLogin(osnID: gimService.mOsnId, osnKey: gimService.mOsnKey, target: appInfo.target, url: jsons["url"] as! String) { json, error in
                if json != nil {
                    self.islogin = true

                    let callback = jsons["callback"] as! String
                    let result = DappSdk.setReply(error: nil, json: json)
                    let resultString = OsnUtils.toString(result)! as String
                    let formattedCallback = "\(callback)(\(resultString))"
                    print("callback: \(formattedCallback)")
                    
                    DispatchQueue.main.async {
                        weakSelf?.webView.evaluateJavaScript(formattedCallback) { _, _ in
                            print("done")
                        }
                    }
                }else{
                    self.islogin = false
                    let callback = jsons["callback"] as! String
                    let result = DappSdk.setReply(error: error, json: nil)
                    let resultString = OsnUtils.toString(result)! as String
                    let formattedCallback = "\(callback)(\(resultString)"
                    
                    DispatchQueue.main.async {
                        weakSelf?.webView.evaluateJavaScript(formattedCallback) { _, _ in
                            print("done")
                        }
                    }
                }
                
            }
        }
        
//        DMCCIMService.getInstance().loginLitapp(withInfo: appInfo, url: (jsons["url"] as! String), success: { json in
//            
//        }, error: { errorCode in
//            self.islogin = false
//        })
    }

    func AddFriend (userId:String) {
        // 判断好友是否已经存在
        let userInfo = gosnUser.getUserInfoDefault(userId)
            if gosnFriend.isFriend(userInfo.userId) {
                let detailVC = UserDetailVC(userInfo: userInfo)
                navigationController?.pushViewController(detailVC, animated: true)
            } else {
                let addFriendVC = AddUserVC(userInfo: userInfo)
                navigationController?.pushViewController(addFriendVC, animated: true)
            }
    }
    
    func GroupInfo (groupId:String) {
        // 判断群组是否已经存在
        if let conv = gosnConversation.getConversationInfo(groupId) {
                // 已存在的群组
            let newConv = gosnConversation.initParam(groupId)//DMCCConversation.init(param: groupId, type: 1)
            let chatVC = ChatVC(conversation: newConv)
            navigationController?.pushViewController(chatVC, animated: true)
            return
        }

        let group = gosnGroup.getGroupInfoDefault(groupId)//GroupInfo.init(null: groupId)
            let addGroupVC = AddGroupVC(group: group)
            navigationController?.pushViewController(addGroupVC, animated: true)
    }
    
    
    func wkWebSetup () {
        
        let osnsdk = """
                var osnsdk = new Object();
                osnsdk.run = function(args){
                    return window.webkit.messageHandlers.osnsdk.postMessage(args);}
        """
        let osnlog = """
                console.log = (function(oriLogFunc){
                    return function(...str){
                        oriLogFunc.call(console,str);
                        window.webkit.messageHandlers.logger.postMessage(str);
                    }
                })(console.log);
                """
        let sdkscript = WKUserScript(source: osnsdk, injectionTime: .atDocumentStart, forMainFrameOnly: true)
        let logscript = WKUserScript(source: osnlog, injectionTime: .atDocumentStart, forMainFrameOnly: true)
//        let messageHandler = WKScriptMessageHandler.self
        userContentController.addUserScript(sdkscript)
        userContentController.addUserScript(logscript)
        userContentController.add(self, name: "osnsdk")
        userContentController.add(self, name: "logger")
        
        let config = WKWebViewConfiguration()
        config.processPool = WKProcessPool()
        config.selectionGranularity = .dynamic
        config.allowsInlineMediaPlayback = true
        let  preferences = WKPreferences()
        preferences.javaScriptEnabled = true
        preferences.javaScriptCanOpenWindowsAutomatically = true
        config.preferences = preferences
        config.userContentController = userContentController
        webView = WKWebView(frame: CGRect(x: 0, y: GKNavHeight, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height - GKNavHeight), configuration: config)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.allowsBackForwardNavigationGestures = true
        webView.navigationDelegate = self
//        webView.backgroundColor = .red
        webView.uiDelegate = self
            //页面后退
        webView.goBack()
            //页面前进
        webView.goForward()
        // 将webView添加到视图控制器的视图上
        view.addSubview(webView)
        
        var url = appInfo.url//appInfo.getUrl()
        var request : URLRequest
        
        if !url.contains("?") {
            url += "?loginType=osn&appId=OSNUiHKrfMduJ1maRZmWvBduYkhfLmHHN4LEpCJXjPWVm9TQBFRc1HoRqHL4eBcrASdAJHzLJMQ3e3";
        }else{
            url += "&loginType=osn&appId=OSNUiHKrfMduJ1maRZmWvBduYkhfLmHHN4LEpCJXjPWVm9TQBFRc1HoRqHL4eBcrASdAJHzLJMQ3e3";
        }
        url += "&language=" + "0";
        url = url + "loginType=osn&appId=OSNUiHKrfMduJ1maRZmWvBduYkhfLmHHN4LEpCJXjPWVm9TQBFRc1HoRqHL4eBcrASdAJHzLJMQ3e3"
        if !dappEnable(for: url) {
            let dappInfo = appInfo.info
            let data = dappInfo.data(using: .utf8)!
            
            // 使用 base64EncodedString(options:) 方法（但没有URL安全的选项）
            let base64EncodedString = data.base64EncodedString()
            
            // 手动替换字符以符合URL安全的要求
            let safeBase64EncodedString = base64EncodedString.replacingOccurrences(of: "+", with: "-")
                                         .replacingOccurrences(of: "/", with: "_")
                                         .trimmingCharacters(in: CharacterSet(charactersIn: "="))
            
            print("Base64 URL Safe Encoded String: \(safeBase64EncodedString)")
            
            let login = gosnLogin.loadLoginData()
            
            let disableUrl = "https://abc.tjlm.top:21000/dapp-forbidden.html?token=\(login["token"] ?? "")&dapp=\(safeBase64EncodedString)"
            
            request = URLRequest(url: URL(string: disableUrl)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 30)
        } else {
            request = URLRequest(url: URL(string: url)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 30)
        }
      
        webView.load(request)
        
    }
    
    func dappEnable(for url: String) -> Bool {
        if let blacklist = KUserDefaults.object(forKey: MHHYCrossImBlacklist) as? [String: Any],
           let blackListArray = blacklist["blackListArray"] as? [String] {
            for str in blackListArray {
                print(str)
                if url.contains(str) {
                    print("黑名单")
                    return false
                }
            }
        }
        return true
    }

}
